<template>
  <div :style="{ cursor, userSelect}" class="vue-splitter-container clearfix" @mouseup="onMouseUp" @mousemove="onMouseMove">

    <pane class="splitter-pane splitter-paneL" :split="split" :style="{ [type]: percent+'%'}">
      <slot name="paneL"></slot>
    </pane>

    <resizer :className="className" :style="{ [resizeType]: percent+'%'}" :split="split" @mousedown.native="onMouseDown" @click.native="onClick"></resizer>

    <pane class="splitter-pane splitter-paneR" :split="split" :style="{ [type]: 100-percent+'%'}">
      <slot name="paneR"></slot>
    </pane>

  </div>
</template>

<script>
import slots from "./slots.js"
import Resizer from "./resizer.vue";
import Pane from "./pane.vue";

export default {
  name: "splitPane",
  mixins: [slots],
  components: { Resizer, Pane },
  props: {
    minPercent: {
      type: Number,
      default: 10
    },
    defaultPercent: {
      type: Number,
      default: 50
    },
    split: {
      validator(value) {
        return ["vertical", "horizontal"].indexOf(value) >= 0;
      },
      required: true
    },
    className: String
  },
  computed: {
    userSelect() {
      return this.active ? "none" : "";
    },
    cursor() {
      return this.active ? "col-resize" : "";
    }
  },
  data() {
    return {
      active: false,
      hasMoved: false,
      height: null,
      percent: this.defaultPercent,
      type: this.split === "vertical" ? "width" : "height",
      resizeType: this.split === "vertical" ? "left" : "top"
    };
  },
  methods: {
    onClick() {
      if (!this.hasMoved) {
        if (this.split === "vertical") {
          if (this.percent > 20 || this.percent === 0) {
            this.percent = 20;
            this.$emit("resize");
          } else {
            this.percent = 0;
            this.$emit("resize");
          }
        } else {
          if (this.percent < 70 || this.percent === 100) {
            this.percent = 70;
            this.$emit("resize");
          } else {
            this.percent = 100;
            this.$emit("resize");
          }
        }
      }
    },
    onMouseDown() {
      this.active = true;
      this.hasMoved = false;
      this.$emit("resize");
      setTimeout(() => this.$emit("resize"), 400);
    },
    onMouseUp() {
      this.active = false;
      this.$emit("resize");
      setTimeout(() => this.$emit("resize"), 400);
    },
    onMouseMove(e) {
      if (e.buttons === 0 || e.which === 0) {
        this.active = false;
      }

      if (this.active) {
        let offset = 0;
        let target = e.currentTarget;
        if (this.split === "vertical") {
          while (target) {
            offset += target.offsetLeft;
            target = target.offsetParent;
          }
        } else {
          while (target) {
            offset += target.offsetTop;
            target = target.offsetParent;
          }
        }

        const currentPage = this.split === "vertical" ? e.pageX : e.pageY;
        const targetOffset =
          this.split === "vertical"
            ? e.currentTarget.offsetWidth
            : e.currentTarget.offsetHeight;
        const percent =
          Math.floor(((currentPage - offset) / targetOffset) * 10000) / 100;

        if (percent > this.minPercent && percent < 100 - this.minPercent) {
          this.percent = percent;
        }

        this.$emit("resize");
        setTimeout(() => this.$emit("resize"), 400);
        this.hasMoved = true;
      }
    }
  }
};
</script>

<style scoped>
.clearfix:after {
  visibility: hidden;
  display: block;
  font-size: 0;
  content: " ";
  clear: both;
  height: 0;
}

.vue-splitter-container {
  height: 100%;
  position: relative;
}
</style>
